#!/usr/bin/env groovy
// @file     YahooOptionsClient
// @author   Mac Radigan
// @purpose  

package sys.finance

import sys.finance.*
import sys.xml.*
import java.util.TimeZone
import java.text.SimpleDateFormat
import groovy.time.*
import static org.w3c.dom.Node.*

public class YahooOptionsClient {

  public static ArrayList<Option> download(String symbol) {
    def data = new ArrayList()
    use([org.codehaus.groovy.runtime.TimeCategory]) {
      def today = new Date()
      data.addAll( download(symbol, today) )
      data.addAll( download(symbol, today + 1.month) )
      data.addAll( download(symbol, today + 2.month) )
      data.addAll( download(symbol, today + 3.month) )
      data.addAll( download(symbol, today + 4.month) )
      data.addAll( download(symbol, today + 5.month) )
      data.addAll( download(symbol, today + 6.month) )
    }
    return data
  }

  public static ArrayList<Option> download(String symbol, Date expiry) {
    def data = new ArrayList()
    def dateFormatter = new SimpleDateFormat( "yyyy-MM" )
    def expiryString = dateFormatter.format( expiry )
    dateFormatter.setTimeZone( TimeZone.getTimeZone( "GMT" ) )
    def url = "http://finance.yahoo.com/q/op?s=${symbol}&m=${expiryString}"
    def doc = XMLUtilities.download(url)
    println "  [yahoo] ${symbol} (${expiryString})"
    //println XMLUtilities.parseToString(doc)
    def xpath = "//html:td[@class='yfnc_h']/node() | //html:td[@class='yfnc_tabledata1']/node()"
    def nodes = XMLUtilities.findNodes(doc, xpath)
    def counter = 0
    def value
    def option
    for (int nodeIndex=0; nodeIndex<nodes.getSnapshotLength()-1; nodeIndex++) {
      def node = (org.w3c.dom.Node)nodes.snapshotItem(nodeIndex)
      if(node && node.getNodeType()!=TEXT_NODE) node = node.getFirstChild()
      if(node && node.getNodeType()!=TEXT_NODE) node = node.getFirstChild()
      if(node && node.getNodeType()!=TEXT_NODE) node = node.getFirstChild()
      if(node && node.getNodeType()!=TEXT_NODE) node = node.getFirstChild()
      if(node) value = node.getNodeValue()
      if(value=="N/A") { 
        value = null
      } else {
        value = value.replaceAll(",", "")
      }
      switch(counter%8) {
        case 0:
          option = new Option()
          if(value) option.strike = Float.parseFloat(value)
          break
	case 1:
	  option.symbol = value
	  break
	case 2:
	  if(value) option.last = Float.parseFloat(value)
	  break
	case 3:
	  if(value) option.change = Float.parseFloat(value)
	  break
	case 4:
	  if(value) option.bid = Float.parseFloat(value)
	  break
	case 5:
	  if(value) option.ask = Float.parseFloat(value)
	  break
	case 6:
	  if(value) option.volume = Float.parseFloat(value)
	  break
	case 7:
	  if(value) option.openInt = Float.parseFloat(value)
	  println option.toString()
	  data.add(option)
	  break
	default:
	  throw new Exception("Unhandled case: ${counter%8}.")
       }
       counter++
    }
    return data
 }

}

/* *EOF* */
